package edu.thu.thss.yxy.sip;

import java.util.StringTokenizer;

import javax.sip.address.Hop;

/**
 * Routing algorithms return a list of hops to which the request is
 * routed.
 * 
 * @author Andy Gao
 *
 */
public class ProxyHop extends Object
implements Hop{
	protected String host;
    protected int port;
    protected String transport;
    protected boolean explicitRoute;  // this is generated from a ROUTE header.
    protected boolean defaultRoute;   // This is generated from the proxy addr
    protected boolean uriRoute;       // This is extracted from the requestURI.
	
    public ProxyHop(String host, int port, String transport) {
		super();
		this.host = host;
		this.port = port;
		this.transport = transport;
	}
    

    /** 
     * Creates new Hop
     *@param hop is a hop string in the form of host:port/Transport
     *@throws IllegalArgument exception if string is not properly formatted or
     * null.
     */
	public ProxyHop(String hop) {
		if (hop == null) {
			throw new IllegalArgumentException("Null arg!");
		}

		StringTokenizer stringTokenizer = new StringTokenizer(hop + "/");
		String hostPort = stringTokenizer.nextToken("/").trim();
		transport = stringTokenizer.nextToken().trim();
		
		if (transport == null || "".equals(transport)) {
			transport = "UDP";
		}
		
		if (transport.compareToIgnoreCase("UDP") != 0
				&& transport.compareToIgnoreCase("TCP") != 0) {
			System.out.println("Bad transport string " + transport);
			throw new IllegalArgumentException(hop);
		}
		
		String portString = null;
		// IPv6 hostport
		if (hostPort.charAt(0) == '[') {
			int rightSqBrackIndex = hostPort.indexOf(']');
			if (rightSqBrackIndex == -1) {
				throw new IllegalArgumentException("Bad IPv6 reference spec");
			}
			host = hostPort.substring(0, rightSqBrackIndex + 1);
			int portColon = hostPort.indexOf(':', rightSqBrackIndex);
			if (portColon != -1) {
				try {
					portString = hostPort.substring(portColon + 1).trim();
				} catch (IndexOutOfBoundsException exc) {
					// Do nothing - handled later
				}
			}
		}
		// IPv6 address and no port
		else if (hostPort.indexOf(':') != hostPort.lastIndexOf(":")) {
			host = '[' + hostPort + ']';
		} else { // no square brackets and a single or zero colons => IPv4
					// hostPort
			int portColon = hostPort.indexOf(':');
			if (portColon == -1) {
				host = hostPort;
			} else {
				host = hostPort.substring(0, portColon).trim();
				try {
					portString = hostPort.substring(portColon + 1).trim();
				} catch (IndexOutOfBoundsException exc) {
					// Do nothing - handled later
				}
			}
		}
		if (host == null || host.equals("")) {
			throw new IllegalArgumentException("no host!");
		}
		if (portString == null || portString.equals("")) {
			port = 5060;
		} else {
			try {
				port = Integer.parseInt(portString);
			} catch (NumberFormatException ex) {
				throw new IllegalArgumentException("Bad port spec");
			}
		}
	}


	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public String getTransport() {
		return transport;
	}

	public void setTransport(String transport) {
		this.transport = transport;
	}

	public boolean isExplicitRoute() {
		return explicitRoute;
	}

	public void setExplicitRoute(boolean explicitRoute) {
		this.explicitRoute = explicitRoute;
	}

	public boolean isDefaultRoute() {
		return defaultRoute;
	}

	public void setDefaultRoute(boolean defaultRoute) {
		this.defaultRoute = defaultRoute;
	}

	public boolean isUriRoute() {
		return uriRoute;
	}

	public void setUriRoute(boolean uriRoute) {
		this.uriRoute = uriRoute;
	}
	
	public String toString()
    {
        return host + ":" + port + "/" + transport;
    }
}
